//Jonathan Flessner
//Assignment 4
//11-May-2014
//Random Test Card for Smithy
//Smithy (13) - draw 3 cards
//if not enough cards in deck/discard, do what you can, so add as many cards as possible up to 3

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "dominion.h"
#include "dominion_helpers.h"
#include "rngs.h"

//these values are included as the other values from dominion.h seem inaccurate
//and provide for poor quality testing without massive number of iterations
//these can be made higher for rarer cases but will require more test
//iterations to catch errors - the vast majority of the time (99%+?) the hand
//count will be between ~1-9 when an action card is played, and usually it will be 5
#define MAX_HAND_COUNT 20
#define MAX_DECK_DISC_COUNT 100

int main(){
	//variables
	int seed = 17;			//numerical seed for reproducing errors
	srand(seed);
	struct gameState *gS = malloc(sizeof(struct gameState));
	int testNum = 1000000;	//num of tests to run
	int j = 0;				//test loop iterator
	int numPlayers = 0;		//num of players in game
	int p = 0;				//current player
	//int i = 0;				//other loop iterator
	int hCards = 0;			//num of cards in hand
	int disCards = 0;		//num of cards in discard
	int deckCards = 0;		//num of cards in deck
	int totalNotHand = 0;	//num of cards in discard + deck
	int oldTotal = 0;		//old total card num
	int newTotal = 0;		//new total card num
	int threeTest = 0;		//num of 3 cards added tests done
	int twoTest = 0;		//num of 2 cards added
	int oneTest = 0;		//num of 1 cards added
	int zeroTest = 0;		//num of 0 cards added
	
	//random tests
	for(j = 0; j < testNum; j++){
		//fill necessary things with realistic numbers
		numPlayers = rand() % 3 + 2;	//2, 3 or 4 players
		p = rand() % numPlayers;		//select random player (0,1,2,3) as p
		gS->whoseTurn = p;				//set turn to players turn
		hCards = rand() % MAX_HAND_COUNT + 1;		//must have card in hand to play card
		gS->handCount[p] = hCards;					//set handCount
		//set random discard and hand card numbers
		disCards = rand() % MAX_DECK_DISC_COUNT;
		gS->discardCount[p] = disCards;
		deckCards = rand() % MAX_DECK_DISC_COUNT;
		gS->deckCount[p] = deckCards;
		oldTotal = hCards + disCards + deckCards;
		totalNotHand = disCards + deckCards;
		
		//play card
		cardEffect(13, 0, 0, 0, gS, 0, 0); //card, no choices 1,2,3, handPos, bonus = 0 also
		
		newTotal = gS->handCount[p] + gS->discardCount[p] + gS->deckCount[p];
		
		//tests
		//test total card number
		// IMPORTANT NOTE: this test should pass. It looks like a bug in the discardCard function
		//a card looks to be trashed instead of discarded as the totals are always one off
		//this is commented out to eliminate clouded results from Smithy effect function but should
		//be dealt with. Uncomment and run once discard function fixed
		/*
		if(oldTotal != newTotal){
			printf("Card totals, including discard, don't match and should.\n");
			printf("Old total = %d\n", oldTotal);
			printf("New Total = %d\n", newTotal);
		}
		*/
		if(totalNotHand >= 3 && hCards + 2 != gS->handCount[p]){
			printf("Hand count not accurate when 3 cards added.\n");
			printf("Expected hand count = %d\n", hCards + 2);	//add 3, discard one, net gain 2
			printf("Actual hand count = %d\n", gS->handCount[p]);
		}
		if(totalNotHand == 2 && hCards + 1 != gS->handCount[p]){
			printf("Hand count not accurate when 2 cards added.\n");
			printf("Expected hand count = %d\n", hCards + 1);	//add 2, discard one, net gain 1
			printf("Actual hand count = %d\n", gS->handCount[p]);
		}
		if(totalNotHand == 1 && hCards != gS->handCount[p]){
			printf("Hand count not accurate when 1 cards added.\n");
			printf("Expected hand count = %d\n", hCards);	//add 1, discard one, net gain 0
			printf("Actual hand count = %d\n", gS->handCount[p]);
		}
		if(totalNotHand <= 0 && hCards - 1 != gS->handCount[p]){
			printf("Hand count not accurate when 0 cards added.\n");
			printf("Expected hand count = %d\n", hCards - 1);	//add 1, discard one, net loss 1
			printf("Actual hand count = %d\n", gS->handCount[p]);
		}
		if(totalNotHand >= 3){
			threeTest++;
		}
		if(totalNotHand == 2){
			twoTest++;
		}
		if(totalNotHand == 1){
			oneTest++;
		}
		if(totalNotHand == 0){
			zeroTest++;
		}
	}
	printf(" Num of 3 card added tests: %d\n Num of 2 card added tests: %d\n Num of 1 card added tests: %d\n Num of 0 card added tests: %d\n", threeTest, twoTest, oneTest, zeroTest);
	return 0;
}